using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.Threading;
using System.Transactions;
using HengTong.Model;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Extensions;
using TiaoTaoHelper.Wtm.Workflow;
using Microsoft.Extensions.DependencyInjection;
using HengTong.Model.Db;
using HengTong.Model.Db.Ai;
using HengTong.Model.Services;
using TiaoTaoHelper.Models;
using UUIDNext;
using HengTong.Model.Db.SupplyChain.Material;
using HengTong.Model.Db.SupplyChain.Warehouse;
using HengTong.ViewModel.SupplyChain.SysWarehouseStockVms;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;


namespace HengTong.ViewModel.SupplyChain.SysMaterialVms
{
    public partial class SysMaterialVm
    {
        private static readonly SemaphoreSlim Slim = new(1, 1);
        public List<SysWarehouseStockView> Stocks { get; set; } = new List<SysWarehouseStockView>();
        public Guid? NoKKeyAttributesPromptId { get; set; }
        public SysMaterialVm()
        {
            SetInclude(x => x.MaterialGroup);
            SetInclude(x => x.Unit);
            SetInclude(x => x.Skus);
        }
        
        protected override void InitVM()
        {
            if (Entity?.ID != null && Entity.ID != Guid.Empty)
            {
                Entity.Attributes = DC.Set<SysMaterialAttribute>()
                    .AsNoTracking()
                    .Include(e => e.Values)
                    .Where(e => e.MaterialId == Entity.ID)
                    .OrderBy(e => e.Order)
                    .ToList();
                var stocks = DC.Set<SysWarehouseStock>()
                    .AsNoTracking()
                    .Include(e => e.Sku)
                    .ThenInclude(e => e.Attributes)
                    .Where(e => e.MaterialId == Entity.ID)
                    .Where(e => e.Quantity > 0)
                    .Select(e => new SysWarehouseStockView
                    {
                        WarehouseName = e.Location.Warehouse.Name,
                        LocationName = e.Location.Name,
                        Quantity = e.Quantity,
                        Sku = e.Sku,
                        SkuId = e.SkuId,
                        MaterialId = e.MaterialId,
                        SkuCode = e.Sku.Code,
                        SkuName = e.Sku.Name,
                        UnitName = e.Sku.Unit.Name,
                        ErpId = e.ErpId,
                        StoreType = e.StoreType
                    })
                    .ToList();
                //循环物料所有属性
                Entity.Attributes?.ForEach(attribute =>
                {
                    //循环物料所有属性值
                    attribute.Values.ForEach(value =>
                    {
                        //遍历库位库存
                        stocks.ForEach(stock =>
                        {
                            //如果库存的SKU包含该属性值，则累加数量
                            if (stock.Sku.Attributes.Any(e => e.ValueId == value.ID))
                            {
                                value.InStock += stock.Quantity;
                            }
                        });
                    });
                });
                stocks.ForEach(e =>
                {
                    e.Sku = null;
                });
                Stocks = stocks;
            }
            var prompt = DC
                .Set<SysPrompt>()
                .FirstOrDefault(e => e.Name == "物料生成采购属性" && e.IsEnabled == true);
            if(prompt != null) 
            {
                NoKKeyAttributesPromptId = prompt.ID;
            }
        }
        
        
        /// <summary>
        /// 生成物料编码, 必须提供物料分组ID
        /// </summary>
        /// <returns></returns>
        public async Task<string> GenerateCodeAsync(Guid groupId)
        {
            await Slim.WaitAsync();
            try
            {
                var group = await DC.Set<SysMaterialGroup>()
                    .FirstOrDefaultAsync(e => e.ID == groupId);
                if (group == null)
                {
                    throw new Exception($"物料分类不存在，无法生成物料编码，分类ID: {groupId}");
                }
                group.SerialNumber++;
                var code = $"{group.Code}-{group.SerialNumber.ToString().PadLeft(4, '0')}";
                await DC.SaveChangesAsync();
                return code;
            }
            finally
            {
                Slim.Release();
            }
        }

    }
}
